package com.ch4;

import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @author woldier
 * @version 1.0
 * @description TODO
 * @date 2023/5/5 13:18
 **/
@Slf4j(topic = "c.Thread")
public class Demo07 {
    public static void main(String[] args) throws InterruptedException {
        GuardedObject2 guardedObject = new GuardedObject2();
        new Thread(()->{
            guardedObject.getResponse(8);

        },"消费者").start();
        TimeUnit.SECONDS.sleep(6);
        new Thread(()->{
            guardedObject.complete("hello");

        },"生产者").start();
    }
}
@Slf4j(topic = "c.Thread")
class GuardedObject2{
    private Object response;

    /**
     * description 同步性线程 消费者 加入超时时间
     *
     * @return java.lang.Object
     * @author: woldier
     * @date: 2023/5/5 8:55
     */
    public synchronized Object getResponse(long timeout) {
        LocalDateTime start = LocalDateTime.now();
        LocalDateTime pass = start;
        int waitTime = (start.plusSeconds(timeout).toLocalTime().toSecondOfDay() - pass.toLocalTime().toSecondOfDay()) * 1000;
        while (response == null) {
            if(start.plusSeconds(timeout).isBefore(pass)){
                break;
            }
            log.debug("消费者等待生产者");
            try {

                this.wait(waitTime);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            pass = LocalDateTime.now();
        }
        log.debug("消费者跳出消费等待");
        return response;
    }

    /**
     *
     * description 同步性线程 消费者 默认超时时间 6000 ms
     *
     *
     * @return java.lang.Object
     * @author: woldier
     * @date: 2023/5/5 13:11
     */
    public synchronized Object getResponse() {
        return getResponse(6);
    }


    /**
     * description 同步线程 生产者
     *
     * @param o 生产者产生的结果
     * @return void
     * @author: woldier
     * @date: 2023/5/5 8:56
     */
    public synchronized void complete(Object o) {
        response = o;
        this.notifyAll();
        log.debug("生产者");
    }
}
